﻿using System;
using System.Collections.Generic;

using System.Text;
using TA.JSON;
using System.ComponentModel;

namespace TA.Turbo
{
	/// <summary>
	/// Specifies a field's data binding parameters.
	/// </summary>
	[TypeConverter(typeof(ExpandableObjectConverter))]
	public class FieldBinding : IJsonCompatible
	{
		/// <summary>
		/// Ctor.
		/// </summary>
		public FieldBinding()
		{
			this.Field = "";
			//this.ServerField = "";
			this.Format = "";
			this.Direction = DataDirection.Both;
			this.StoringType = ValidationDataType.String;
			this.BindingType = ValidationDataType.String;
		}

		/// <summary>
		/// The name or path of the data field which will be bound to this field on the client.
		/// </summary>
		[DefaultValue("")]
		[NotifyParentProperty(true)]
		public string Field { get; set; }
		///// <summary>
		///// The name or path of the data field which will be bound to this field on the server.
		///// </summary>
		//[DefaultValue("")]
		//[NotifyParentProperty(true)]
		//public string ServerField { get; set; }
		/// <summary>
		/// Binding direction. 'Bind' assigns the value to the control and 'Store' save the control's value in the bound object.
		/// </summary>
		[DefaultValue(DataDirection.Both)]
		[NotifyParentProperty(true)]
		public DataDirection Direction { get; set; }
		/// <summary>
		/// The data type to be used for conversion when binding data to UI element.
		/// </summary>
		[DefaultValue(ValidationDataType.String)]
		[NotifyParentProperty(true)]
		public ValidationDataType BindingType { get; set; }
		/// <summary>
		/// The data type to be used for conversion when storing data from UI element.
		/// </summary>
		[DefaultValue(ValidationDataType.String)]
		[NotifyParentProperty(true)]
		public ValidationDataType StoringType { get; set; }
		/// <summary>
		/// Format string used when displaying the value as a string.
		/// </summary>
		[DefaultValue("")]
		[NotifyParentProperty(true)]
		public string Format { get; set; }
		/// <summary>
		/// Sets the properties of this FieldBinding to be equal to those of the parameter.
		/// </summary>
		/// <param name="f"></param>
		public void Set(FieldBinding f)
		{
			this.Field = f.Field;
			this.Direction = f.Direction;
			this.StoringType = f.StoringType;
			this.BindingType = f.BindingType;
			this.Format = f.Format;
			//this.ServerField = f.ServerField;
		}
		#region IJsonSerializable Members

		/// <summary>
		/// IsDirty.
		/// </summary>
		[Browsable(false)]
		[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
		public bool IsDirty
		{
			get
			{
				return
					!string.IsNullOrEmpty(this.Field)
					|| !string.IsNullOrEmpty(this.Format)
					|| this.Direction != DataDirection.Both
					|| this.StoringType != ValidationDataType.String
					|| this.BindingType != ValidationDataType.String;
			}
		}

		/// <summary>
		/// Serialize.
		/// </summary>
		/// <param name="jw"></param>
		public void Serialize(JsonWriter jw)
		{
			this.SerializeObject(jw);
		}
		/// <summary>
		/// SerializeContents.
		/// </summary>
		/// <param name="jw"></param>
		public void SerializeContents(JsonWriter jw)
		{
			if (!string.IsNullOrEmpty(this.Field))
			{
				jw.PropertyName("F");
				jw.Value(this.Field);
			}

			if (!string.IsNullOrEmpty(this.Format))
			{
				jw.PropertyName("O");
				jw.Value(this.Format);
			}

			if (this.Direction != DataDirection.Both)
			{
				jw.PropertyName("D");
				jw.Value(this.Direction);
			}

			if (this.StoringType != ValidationDataType.String)
			{
				jw.PropertyName("S");
				jw.Value(this.StoringType);
			}

			if (this.BindingType != ValidationDataType.String)
			{
				jw.PropertyName("B");
				jw.Value(this.BindingType);
			}
		}

		#endregion

		#region IJsonDeserializable Members
		/// <summary>
		/// Deserialize.
		/// </summary>
		/// <param name="jr"></param>
		public void Deserialize(IJsonReader jr)
		{
			this.DeserializeObject(jr);
		}
		/// <summary>
		/// DeserializeContent.
		/// </summary>
		/// <param name="jr"></param>
		/// <param name="propShortName"></param>
		public void DeserializeContent(IJsonReader jr, string propShortName)
		{
			switch (propShortName)
			{
				case "F": this.Field = (string)jr.Value; break;
				case "O": this.Format = (string)jr.Value; break;
				case "T": this.StoringType = (ValidationDataType)(long)jr.Value; break;
				case "D": this.Direction = (DataDirection)(long)jr.Value; break;
			}

		}

		#endregion
	}
}
